package cn.chaozhoubang.vmall.backend.controller.impl;

import cn.chaozhoubang.vmall.backend.annotation.AuthRequire;
import cn.chaozhoubang.vmall.backend.controller.MenuController;
import cn.chaozhoubang.vmall.backend.mapper.*;
import cn.chaozhoubang.vmall.backend.model.*;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @Todo 鱼仔写
 */
@RestController
@RequestMapping("/api/private/v1")
public class MenuControllerImpl implements MenuController {

    private PermissionMapper permissionMapper;
    private PermissionApiMapper permissionApiMapper;
    private ManagerMapper managerMapper;
    private RoleMapper roleMapper;
    private HttpServletRequest request;
    private HttpServletResponse response;

    private JSONObject buildDataNode(SpPermission spPermission, boolean isTree, String ids) {
        final JSONObject object = new JSONObject();
        final QueryWrapper<SpPermissionApi> wrapper = new QueryWrapper<>();
        wrapper.eq("ps_id", spPermission.getPsId());
        SpPermissionApi permissionApi = permissionApiMapper.selectOne(wrapper);
        object.set("id", spPermission.getPsId())
                .set("authName", spPermission.getPsName())
                .set("level", spPermission.getPsLevel())
                .set("pid", spPermission.getPsPid())
                .set("path", permissionApi == null? null: permissionApi.getPsApiPath());
        if(isTree) object.set("children", buildChildren(spPermission, ids));
        return object;
    }

    private JSONObject buildDataNode(SpPermission spPermission, String ids) {
        return buildDataNode(spPermission, true, ids);
    }

    private JSONObject buildDataNode(SpPermission spPermission) {
        return buildDataNode(spPermission, true, null);
    }

    private JSONObject buildDataNode(SpPermission spPermission, boolean isTree) {
        return buildDataNode(spPermission, isTree, null);
    }

    private JSONArray buildListData(List<SpPermission> permissions) {
        JSONArray array = new JSONArray();
        for(SpPermission permission: permissions) {
            array.add(buildDataNode(permission, false));
        }
        return array;
    }

    private JSONArray buildChildren(SpPermission spPermission, String ids) {
        final JSONArray array = new JSONArray();
        final QueryWrapper<SpPermission> childPermissionWrapper = new QueryWrapper<>();
        childPermissionWrapper.eq("ps_pid", spPermission.getPsId());
        List<SpPermission> list = permissionMapper.selectList(childPermissionWrapper);
        for(SpPermission child: list) {
            if(ids != null) {
                if(!ids.contains(String.valueOf(child.getPsId())))
                    continue;
            }
            array.add(buildDataNode(child));
        }
        return array;
    }


    private JSONArray buildTreeData(List<SpPermission> permissions, String ids) {
        final JSONArray array = new JSONArray();
        for(SpPermission permission: permissions) {
            if(ids != null) {
                if(!ids.contains(String.valueOf(permission.getPsId())))
                    continue;
            }
            array.add(buildDataNode(permission, ids));
        }
        return array;
    }

    private JSONArray buildTreeData(List<SpPermission> permissions) {
        return buildTreeData(permissions, null);
    }

    private JSONObject buildMeta(int status, String msg) {
        final JSONObject meta = new JSONObject();
        meta.set("status", status);
        meta.set("msg", msg);
        return meta;
    }

    private JSONObject buildResult(JSONObject meta, JSONArray data) {
        final JSONObject res = new JSONObject();
        res.set("meta", meta);
        res.set("data", data);
        return res;
    }

    private JSONObject buildResult(JSONObject meta, JSONObject data) {
        final JSONObject res = new JSONObject();
        res.set("meta", meta);
        res.set("data", data);
        return res;
    }

    @Override
    @AuthRequire
    @RequestMapping(value = "/rights/{type}", produces = "application/json;charset=UTF-8")
    public String getRights(@PathVariable String type) {
        if("list".equals(type)) {
            final List<SpPermission> list = permissionMapper.selectList(null);
            final JSONArray data = buildListData(list);
            final JSONObject meta = buildMeta(200, "获取权限列表成功!");
            return buildResult(meta, data).toString();
        }
        QueryWrapper<SpPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("ps_pid", 0);
        final List<SpPermission> list = permissionMapper.selectList(wrapper);
        final JSONArray data = buildTreeData(list);
        final JSONObject meta = buildMeta(200, "获取权限列表成功");
        return buildResult(meta, data).toString();
    }

    @Override
    @AuthRequire
    @RequestMapping(value = "/menus", produces = "application/json;charset=UTF-8")
    public String getMenus() {
        String auth = (String) request.getSession().getAttribute("username");
        if(auth == null || "".equals(auth)) {
            try {
                response.sendError(HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
        final QueryWrapper<SpManager> managerQueryWrapper = new QueryWrapper<>();
        managerQueryWrapper.eq("mg_name", auth);
        final SpManager manager = managerMapper.selectOne(managerQueryWrapper);
        if(manager == null) {
            try {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
        final QueryWrapper<SpRole> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("role_id", manager.getRoleId());
        final SpRole role = roleMapper.selectOne(roleQueryWrapper);
        if(role == null) {
            try {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
        QueryWrapper<SpPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("ps_pid", 0);
        final List<SpPermission> list = permissionMapper.selectList(wrapper);
        final JSONArray data = buildTreeData(list, role.getPsIds());
        final JSONObject meta = buildMeta(200, "获取权限列表成功");
        return buildResult(meta, data).toString();
    }

    @Override
    @AuthRequire
    @GetMapping(value = "/roles", produces = "application/json;charset=UTF-8")
    public String getRoles() {
        final JSONArray data = new JSONArray();
        List<SpRole> roles = roleMapper.selectList(null);
        final QueryWrapper<SpPermission> wrapper = new QueryWrapper<>();
        final List<SpPermission> permissions = permissionMapper.selectList(wrapper);
        wrapper.eq("ps_pid", 0);
        for(SpRole role: roles) {
            final JSONObject object = new JSONObject();
            final JSONArray children = buildTreeData(permissions, role.getPsIds());
            object.set("children", children);
            object.set("id", role.getRoleId());
            object.set("roleDesc", role.getRoleDesc());
            object.set("roleName", role.getRoleName());
            data.add(object);
        }
        return buildResult(buildMeta(200, "获取成功"), data).toString();
    }

    @Override
    @PostMapping(value = "/roles", produces = "application/json;charset=UTF-8")
    public String addRole(@RequestBody SpRole role) {
        final int rs = roleMapper.insert(role);
        if(rs > 0) {
            return buildResult(buildMeta(201, "修改成功"), new JSONObject()).toString();
        }
        return buildResult(buildMeta(500, "修改失败"), new JSONObject()).toString();
    }

    @Override
    @GetMapping(value = "/roles/{id}", produces = "application/json;charset=UTF-8")
    public String getRole(@PathVariable int id) {
        final JSONObject data = new JSONObject();
        final QueryWrapper<SpRole> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("role_id", id);
        SpRole role = roleMapper.selectOne(roleQueryWrapper);
        data.set("roleId", role.getRoleId());
        data.set("roleDesc", role.getRoleDesc());
        data.set("roleName", role.getRoleName());
        data.set("rolePermissionDesc", null);
        return buildResult(buildMeta(200, "获取成功"), data).toString();
    }

    @Override
    @PutMapping(value = "/roles/{id}", produces = "application/json;charset=UTF-8")
    public String putRole(@RequestBody SpRole role, @PathVariable int id) {
        if(role == null)
            return buildResult(buildMeta(400, "BAD REQUEST"), new JSONObject()).toString();
        role.setRoleId(id);
        System.out.println(role);
        final int rs = roleMapper.updateById(role);
        if(rs > 0) {
            JSONObject data = new JSONObject();
            data.set("roleId", role.getRoleId());
            data.set("roleDesc", role.getRoleDesc());
            data.set("roleName", role.getRoleName());
            data.set("rolePermissionDesc", null);
            return buildResult(buildMeta(200, "修改成功"), data).toString();
        }
        return buildResult(buildMeta(500, "修改失败"), new JSONObject()).toString();
    }

    @Override
    @DeleteMapping(value = "/roles/{id}", produces = "application/json;charset=UTF-8")
    public String deleteRole(@PathVariable int id) {
        final int rs = roleMapper.deleteById(id);
        if(rs > 0) {
            return buildResult(buildMeta(200, "修改成功"), new JSONObject()).toString();
        }
        return buildResult(buildMeta(500, "修改失败"), new JSONObject()).toString();
    }

    @Override
    @PostMapping(value = "/roles/{id}/rights", produces = "application/json;charset=UTF-8")
    public String postRight(@RequestBody SpRole role, @PathVariable int id) {
        if(role == null)
            return buildResult(buildMeta(400, "BAD REQUEST"), new JSONObject()).toString();
        System.out.println(role);
        final UpdateWrapper<SpRole> roleUpdateWrapper = new UpdateWrapper<>();
        roleUpdateWrapper.set("ps_ids", role.getPsIds());
        roleUpdateWrapper.eq("role_id", id);
        final int rs = roleMapper.update(null, roleUpdateWrapper);
        if(rs > 0) {
            return buildResult(buildMeta(200, "修改成功"), new JSONObject()).toString();
        }
        return buildResult(buildMeta(500, "修改失败"), new JSONObject()).toString();
    }

    @Autowired
    public void setPermissionApiMapper(PermissionApiMapper permissionApiMapper) {
        this.permissionApiMapper = permissionApiMapper;
    }

    @Autowired
    public void setPermissionMapper(PermissionMapper permissionMapper) {
        this.permissionMapper = permissionMapper;
    }

    @Autowired
    public void setRoleMapper(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    @Autowired
    public void setManagerMapper(ManagerMapper managerMapper) {
        this.managerMapper = managerMapper;
    }

    @Autowired
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    @Autowired
    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }
}
